package com.runas.cartesian;

import com.runas.util.SemanticBlockUtil;
import com.runas.util.ZipUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;

import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Hello world!
 */
public class App {
    private static ExecutorService service = Executors.newCachedThreadPool();
    public static ObjectMapper om = new ObjectMapper();


    private static void unzip() throws Exception {
        URL url = Thread.currentThread().getContextClassLoader().getResource("sources.zip");
        if (url == null) System.out.println("NOT Found file sources.zip.");
        File sourceTgz = new File(url.getPath());
        ZipUtil.unzip(FileUtils.readFileToByteArray(sourceTgz), new File(sourceTgz.getParent()));
    }

    public static void main(String args[]) throws Exception {
        URL url = Thread.currentThread().getContextClassLoader().getResource("sources");
        if (url == null) {
            unzip();
            url = Thread.currentThread().getContextClassLoader().getResource("sources");
        }
        File sourceDir = new File(url.getPath());
        if (sourceDir != null) {
            final CountDownLatch count = new CountDownLatch(sourceDir.listFiles().length);
            final File targetDir = new File(sourceDir.getParent(), "target");
            if (!targetDir.exists()) targetDir.mkdirs();
            // 按照文件大小排序
            List<File> fileList = Arrays.asList(sourceDir.listFiles());
            Collections.sort(fileList, new Comparator<File>() {
                public int compare(File f1, File f2) {
                    return (int) (f1.length() - f2.length());
                }
            });
            for (final File f : fileList) {
                service.submit(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            readFile(f, targetDir, count);
                            FileUtils.moveFileToDirectory(f, new File(targetDir, "original"), true);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
            count.await();
            System.out.println("finish.");
        }

    }

    /**
     * 读入TXT文件
     */
    public static void readFile(File f, File targetDir, CountDownLatch count) {
        FileReader reader = null;
        BufferedReader br = null;
        FileWriter writer = null;
        final Set<String> cache = new HashSet<String>();
        try {
            reader = new FileReader(f);
            br = new BufferedReader(reader);
            String line;

            File targetFile = new File(targetDir, f.getName());
            if (targetFile.exists()) {
                targetFile.delete();
            }
            targetFile.createNewFile();
            writer = new FileWriter(targetFile);
            final BufferedWriter out = new BufferedWriter(writer);
            while ((line = br.readLine()) != null) {
                final TempClass temp = om.readValue(line, TempClass.class);
                SemanticBlockUtil.SingleParsedBlocks<String> block = new SemanticBlockUtil.SingleParsedBlocks<String>(temp.getList(), null);
                block.arrangePlain(new SemanticBlockUtil.ArrangeCallBack<String>() {
                    public void call(List<String> blocks) {
                        String r = StringUtils.join(blocks, "");
                        if (cache.add(r)) {
                            try {
                                out.write(temp.getStdQ() + " - " + r + "\r\n");
                                out.flush();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                });
            }
            if (out != null)
                out.close();
            count.countDown();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (reader != null)
                    reader.close();
                if (br != null)
                    br.close();
                if (writer != null)
                    writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
